package dnl.jexem.cmd;

import java.io.Serializable;
import java.util.Arrays;
import org.apache.commons.lang.StringUtils;

/**
 * Encapsulates a generic command that includes the command string and arguments.
 *
 * @author Daniel Orr
 */
public class Command implements Serializable {

    private static final long serialVersionUID = 1L;

    protected String command;
    protected String[] args;

    /**
     * Constructs a new {@code Command} object.
     *
     * @param command a {@code String} that contains the command and its arguments, if there are any.
     */
    public Command(String command) {
        String[] cmd = StringUtils.split(command, " ");
        this.command = cmd[0];
        this.args = Arrays.copyOfRange(cmd, 1, cmd.length);
    }

    /**
     * Constructs a new {@code Command} object.
     *
     * @param command an array of strings which first element is the command and the rest are arguments.
     */
    public Command(String... command) {
        this.command = command[0];
        this.args = Arrays.copyOfRange(command, 1, command.length);
    }

    /**
     * Gets the full command string (command+arguments).
     *
     * @return concatenation of the command and its arguments.
     */
    public String getFullCommand() {
        StringBuilder sb = new StringBuilder(command);
        for (String arg : args) {
            sb.append(" ");
            sb.append(arg);
        }
        return sb.toString();
    }

    /**
     * Gets the command part. For example if the command is 'tar cvzf mmm.tar.gz dirname' then the command is
     * 'tar'.
     *
     * @return the main command.
     */
    public String getCommand() {
        return command;
    }

    /**
     * Gets the arguments only.For example if the command is 'tar cvzf mmm.tar.gz dirname' then the argments
     * are 'cvzf mmm.tar.gz dirname'.
     *
     * @return only the command's arguments.
     */
    public String[] getArgs() {
        return args;
    }

    /**
     * An internal id.
     *
     * @return
     */
    public String getId() {
        return String.valueOf(hashCode());
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + Arrays.hashCode(args);
        result = prime * result + ((command == null) ? 0 : command.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Command other = (Command) obj;
        if (!Arrays.equals(args, other.args)) {
            return false;
        }
        if (command == null) {
            if (other.command != null) {
                return false;
            }
        } else if (!command.equals(other.command)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Command [args=" + Arrays.toString(args) + ", command=" + command + "]";
    }

}
